package com.project.poetry.service.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.poetry.common.constant.ConstantValue;
import com.project.poetry.common.util.CommonUtil;
import com.project.poetry.service.entity.dto.poetry.PoetryAuthorDTO;
import com.project.poetry.service.entity.dto.poetry.PoetryDTO;
import com.project.poetry.service.entity.dto.poetry.PoetryListDTO;
import com.project.poetry.service.entity.dto.poetry.PoetryListOutDTO;
import com.project.poetry.service.entity.po.author.AuthorPO;
import com.project.poetry.service.entity.po.poetry.PoetryPO;
import com.project.poetry.service.mapper.PoetryMapper;
import com.project.poetry.service.service.AuthorService;
import com.project.poetry.service.service.PoetryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 作品业务层实现类
 * @author mengxj
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PoetryServiceImpl extends ServiceImpl<PoetryMapper, PoetryPO> implements PoetryService {

    @Resource
    private PoetryMapper poetryMapper;

    @Resource
    private AuthorService authorService;

    @Override
    public PoetryDTO getPoetryDetail(Long poetryId) {
        PoetryDTO poetry = new PoetryDTO();
        PoetryPO po = super.getById(poetryId);
        poetry.setId(poetryId);
        poetry.setTitle(po.getTitle());
        poetry.setPreface(po.getPreface());
        poetry.setPosition(po.getPosition());
        poetry.setSentence(JSON.parseArray(po.getContent(), String.class));
        AuthorPO author = this.authorService.getById(po.getAuthorId());
        poetry.setAuthor(author);
        return poetry;
    }

    @Override
    public void savePoetry(PoetryDTO poetry) {
        Long id = poetry.getId();
        boolean hasId = Objects.isNull(id);
        PoetryPO po;
        String title = poetry.getTitle();
        if(hasId){
            List<PoetryPO> list = this.poetryMapper.selectList(new QueryWrapper<PoetryPO>().lambda().eq(PoetryPO :: getTitle, title));
            CommonUtil.checkThrow(CommonUtil :: isNotEmpty, list, ConstantValue.SERVICE_DATA_ERROR_STATUS_CODE, "当前作品已存在！！！");
            po = new PoetryPO();
            this.setPoetry(poetry, po);
            this.poetryMapper.insert(po);
        } else{
            po = super.getById(id);
            this.setPoetry(poetry, po);
            this.poetryMapper.updateById(po);
        }
    }

    private void setPoetry(PoetryDTO poetry, PoetryPO po){
        Integer position = poetry.getPosition();
        position = Objects.isNull(position) ? 0 : Math.max(poetry.getPosition(), 0);
        String[] sentence = CommonUtil.splitPoetryToArray(poetry.getText().trim(), position);
        String json = JSONObject.toJSONString(sentence);
        po.setFirstSentence(sentence[0]);
        po.setTitle(poetry.getTitle());
        po.setAuthorId(poetry.getAuthorId());
        po.setContent(json);
        po.setType(poetry.getType());
        po.setPosition(position);
        po.setPreface(poetry.getPreface());
        po.setSyncStatus(0);
    }

    @Override
    public IPage<PoetryListOutDTO> poetryList(PoetryListDTO poetryList) {
        Integer pageNum = poetryList.getPageNum();
        Integer pageSize = poetryList.getPageSize();
        String text = poetryList.getText();
        if(StrUtil.isBlank(text)){
            QueryWrapper<PoetryListOutDTO> wrapper = new QueryWrapper<>();
            CommonUtil.like(wrapper, "tp.title", poetryList.getTitle());
            CommonUtil.eqNumber(wrapper, "ta.id", poetryList.getAuthor());
            CommonUtil.eq(wrapper, "ta.dynasty", poetryList.getDynasty());
            CommonUtil.eqNumber(wrapper, "tp.type", poetryList.getType());
            wrapper.last("order by sd.code, ta.id, sc.code");
            return this.poetryMapper.selectPoetryList(CommonUtil.getPage(pageNum, pageSize), wrapper);
        }else{
            QueryWrapper<PoetryListOutDTO> wrapper = new QueryWrapper<>();
            CommonUtil.like(wrapper, "tp.title", poetryList.getTitle());
            CommonUtil.eqNumber(wrapper, "ta.id", poetryList.getAuthor());
            CommonUtil.eq(wrapper, "ta.dynasty", poetryList.getDynasty());
            CommonUtil.like(wrapper, "tps.sentence", text);
            CommonUtil.eqNumber(wrapper, "tp.type", poetryList.getType());
            wrapper.last("order by sd.code, ta.id, sc.code, tp.id, tps.order_number");
            return this.poetryMapper.selectPoetrySentenceList(CommonUtil.getPage(pageNum, pageSize), wrapper);
        }
    }

    @Override
    public List<PoetryAuthorDTO> poetryAuthor() {
        return this.poetryMapper.poetryAuthor();
    }

    @Override
    public List<PoetryListOutDTO> poetryListFile(PoetryListDTO poetryList) {
        List<PoetryListOutDTO> list = this.poetryMapper.selectPoetryListFile(poetryList);
        list.forEach(dto -> {
            String preface = dto.getPreface();
            String text = CommonUtil.convertJsonToString(dto.getText());
            if(Objects.isNull(preface)){
                dto.setText(text);
            }else {
                dto.setText(preface + ConstantValue.SPLIT_PREFACE_CONTENT + text);
            }
        });
        return list;
    }

    @Override
    public List<PoetryPO> selectPoetryByAuthorId(Long authorId) {
        return this.poetryMapper.selectList(new QueryWrapper<PoetryPO>().lambda()
                .eq(PoetryPO :: getAuthorId, authorId));
    }

    @Override
    public List<String> getContentListByKeyWord(String keyWord) {
        List<PoetryPO> poetryList = this.poetryMapper.selectList(new QueryWrapper<>());
        return poetryList.stream()
                .map(poetry -> JSON.parseArray(poetry.getContent(), String.class))
                .flatMap(Collection :: stream)
                .filter(content -> content.contains(keyWord))
                .collect(Collectors.toList());
    }
}
